﻿namespace NetOwls.Tutorials.Mqtt.Common.Subscriptions
{
    using System;
    using System.Diagnostics;
    using System.Text;
    using System.Threading.Tasks;
    using MQTTnet;
    using MQTTnet.Client;

    /// <summary>
    ///     提供了简易的 MQTT 消息订阅方法。
    /// </summary>
    /// <seealso>
    ///     <cref>IMessageSubscription</cref>
    /// </seealso>
    /// <seealso>
    ///     <cref>Common.IMqttConnection</cref>
    /// </seealso>
    /// <seealso>
    ///     <cref>System.Threading.Tasks.Task</cref>
    /// </seealso>
    public class SimpleMessageSubscription : IMessageSubscription
    {
        #region Constructors

        /// <summary>
        ///     用于初始化一个 <see cref="SimpleMessageSubscription" /> 对象实例
        /// </summary>
        /// <param name="connection">
        ///     MQTT 服务连接对象。
        ///     <para>
        ///         实现了
        ///         <see>
        ///             <cref>IMqttConnection</cref>
        ///         </see>
        ///         接口的对象实例。
        ///     </para>
        /// </param>
        /// <seealso>
        ///     <cref>Common.IMqttConnection</cref>
        /// </seealso>
        public SimpleMessageSubscription(IMqttConnection connection)
        {
            Connection = connection;
        }

        #endregion

        #region Properties

        #region IMessageSubscription Implements

        /// <summary>
        ///     获取 MQTT 服务连接对象。
        /// </summary>
        public IMqttConnection Connection { get; }

        #endregion

        #endregion

        #region Methods

        #region IMessageSubscription Implements

        /// <summary>
        ///     确定从 MQTT 订阅消息。
        /// </summary>
        /// <returns>
        ///     <see>
        ///         <cref>Task</cref>
        ///     </see>
        ///     类型的对象实例。
        /// </returns>
        /// <seealso>
        ///     <cref>System.Threading.Tasks.Task</cref>
        /// </seealso>
        public async Task EnsureSubscribeAsync()
        {
            await InternalEnsureSubscribeAsync();
        }

        #endregion

        #endregion

        #region Protected Methods

        /// <summary>
        ///     确定要从 MQTT 订阅消息。
        /// </summary>
        /// <returns>
        ///     <see>
        ///         <cref>Task</cref>
        ///     </see>
        ///     类型的对象实例。
        /// </returns>
        /// <seealso>
        ///     <cref>System.Threading.Tasks.Task</cref>
        /// </seealso>
        protected virtual async Task InternalEnsureSubscribeAsync()
        {
            try
            {
                await Connection.ConnectAsync();
                Connection.Client.ApplicationMessageReceived += OnAfterReceived;
                await Connection.Client.SubscribeAsync("topic/testings");
            }
            catch (Exception error)
            {
                Trace.TraceError($"尝试从 MQTT 订阅消息时，引发了一个 {error.GetType().FullName} 类型的异常: {error.Message}");
            }
        }

        #endregion

        #region Event Handlers

        private void OnAfterReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
        {
            Trace.TraceInformation($"订阅消息: {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)} (时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss})");
        }

        #endregion
    }
}